# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
#     https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
#     https://docs.fastlane.tools/plugins/available-plugins
#

# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane

default_platform(:ios)

platform :ios do
  # Development
  desc "Lint code"
  lane :lint_code do
    puts("Lint code using SwfitLint")
    swiftlint(
      mode: :lint,
      executable: "./Pods/SwiftLint/swiftlint",  # The SwiftLint binary path (optional). Important if you've installed it via CocoaPods
      config_file: './Moments/.swiftlint.yml',
      raise_if_swiftlint_error: true)
  end

  desc "Lint and format code"
  lane :format_code do
    puts("Lint and format code using SwfitLint")
    swiftlint(
      mode: :autocorrect,
      executable: "./Pods/SwiftLint/swiftlint",  # The SwiftLint binary path (optional). Important if you've installed it via CocoaPods
      config_file: './Moments/.swiftlint.yml',
      raise_if_swiftlint_error: true)
  end

  desc "Sort Xcode project files"
  lane :sort_files do
    puts("Sort the files for the Xcode project")
    sh "../scripts/sort-Xcode-project-file.pl ../Moments/Moments.xcodeproj"
  end

  desc "Prepare for a pull request"
  lane :prepare_pr do
    format_code
    sort_files
  end

  desc "Build development app"
  lane :build_dev_app do
    puts("Build development app")
    gym(scheme: "Moments",
      workspace: "Moments.xcworkspace",
      export_method: "development",
      configuration: "Debug",
      xcargs: "-allowProvisioningUpdates")
  end

  # Test
  desc "Run unit tests"
  lane :tests do
    puts("Run the tests")
    scan(
      scheme: "Moments", 
      workspace: "Moments.xcworkspace",
      output_directory: "./fastlane/dist", 
      output_types: "html", 
      buildlog_path: "./fastlane/dist")
  end

  # Profile
  desc "Download certificates and profiles"
  lane :download_profiles do
    keychain_name = "TemporaryKeychain"
    keychain_password = "TemporaryKeychainPassword"

    create_keychain(
      name: keychain_name,
      password: keychain_password,
      default_keychain: false,
      timeout: 3600,
      unlock: true,
    )

    match(
      type: "adhoc",
      readonly: true,
      keychain_name: keychain_name,
      keychain_password: keychain_password,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments.internal",
      team_id: "6HLFCRTYQU"
    )

    match(
      type: "appstore",
      readonly: true,
      keychain_name: keychain_name,
      keychain_password: keychain_password,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments",
      team_id: "6HLFCRTYQU"
    )
  end

  desc "Create all new provisioning profiles managed by fastlane match"
  lane :create_new_profiles do
    api_key = get_app_store_connect_api_key
    keychain_name = "TemporaryKeychain"
    keychain_password = "TemporaryKeychainPassword"

    create_keychain(
      name: keychain_name,
      password: keychain_password,
      default_keychain: false,
      timeout: 3600,
      unlock: true,
    )

    match(
      type: "adhoc",
      keychain_name: keychain_name,
      keychain_password: keychain_password,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments.internal",
      team_id: "6HLFCRTYQU",
      api_key: api_key
    )

    match(
      type: "appstore",
      keychain_name: keychain_name,
      keychain_password: keychain_password,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments",
      team_id: "6HLFCRTYQU",
      api_key: api_key
    )
  end

  desc "Nuke all provisioning profiles managed by fastlane match"
  lane :nuke_profiles do
    api_key = get_app_store_connect_api_key
    keychain_name = "TemporaryKeychain"
    keychain_password = "TemporaryKeychainPassword"

    create_keychain(
      name: keychain_name,
      password: keychain_password,
      default_keychain: false,
      timeout: 3600,
      unlock: true,
    )

    match_nuke(
      type: "adhoc",
      keychain_name: keychain_name,
      keychain_password: keychain_password,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments.internal",
      team_id: "6HLFCRTYQU",
      api_key: api_key
    )

    match_nuke(
      type: "appstore",
      keychain_name: keychain_name,
      keychain_password: keychain_password,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments",
      team_id: "6HLFCRTYQU",
      api_key: api_key
    )
  end

  desc "Add a new device to provisioning profile"
  lane :add_device do |options|
    name = options[:name]
    udid = options[:udid]
    
    # Add to App Store Connect
    api_key = get_app_store_connect_api_key
    register_device(
      name: name,
      udid: udid,
      team_id: "6HLFCRTYQU",
      api_key: api_key
    )

    # Update the profiles to Git private repo
    match(
      type: "adhoc",
      force: true,
      storage_mode: "git",
      git_url: "https://github.com/JakeLin/moments-codesign",
      app_identifier: "com.ibanimatable.moments.internal",
      team_id: "6HLFCRTYQU",
      api_key: api_key
    )
  end

  # Archive
  desc 'Creates an archive of the Internal app for testing'
  lane :archive_internal do
    unlock_keychain(
      path: "TemporaryKeychain-db",
      password: "TemporaryKeychainPassword")

    update_code_signing_settings(
      use_automatic_signing: false,
      path: "Moments/Moments.xcodeproj",
      code_sign_identity: "iPhone Distribution",
      bundle_identifier: "com.ibanimatable.moments.internal",
      profile_name: "match AdHoc com.ibanimatable.moments.internal")

    puts("Create an archive for Internal testing")
    gym(scheme: "Moments-Internal",
      workspace: "Moments.xcworkspace",
      export_method: "ad-hoc",
      xcargs: "-allowProvisioningUpdates")

    update_code_signing_settings(
      use_automatic_signing: true,
      path: "Moments/Moments.xcodeproj")
    
    puts("If you run this lane on your local machine, should not commit the changes for your project file to Git")
  end

  desc 'Creates an archive of the Production app with Appstore distribution'
  lane :archive_appstore do
    unlock_keychain(
      path: "TemporaryKeychain-db",
      password: "TemporaryKeychainPassword")

    update_code_signing_settings(
      use_automatic_signing: false,
      path: "Moments/Moments.xcodeproj",
      code_sign_identity: "iPhone Distribution",
      bundle_identifier: "com.ibanimatable.moments",
      profile_name: "match AppStore com.ibanimatable.moments")

    puts("Create an archive for AppStore submission")
    gym(scheme: "Moments-AppStore",
      workspace: "Moments.xcworkspace",
      export_method: "app-store",
      xcargs: "-allowProvisioningUpdates")

    update_code_signing_settings(
      use_automatic_signing: true,
      path: "Moments/Moments.xcodeproj")
    
    puts("If you run this lane on your local machine, should not commit the changes for your project file to Git")
  end

  # Crash report symbols
  desc 'Upload symbols to Crashlytics for Internal app'
  lane :upload_symbols_to_crashlytics_internal do
    upload_symbols_to_crashlytics(
      dsym_path: "./Moments.app.dSYM.zip",
      gsp_path: "./Moments/Moments/Configurations/Firebase/GoogleService-Info-Internal.plist",
      api_token: ENV["FIREBASE_API_TOKEN"]
    )
  end

  desc 'Upload symbols to Crashlytics for Production app'
  lane :upload_symbols_to_crashlytics_appstore do
    upload_symbols_to_crashlytics(
      dsym_path: "./Moments.app.dSYM.zip",
      gsp_path: "./Moments/Moments/Configurations/Firebase/GoogleService-Info-AppStore.plist",
      api_token: ENV["FIREBASE_API_TOKEN"]
    )
  end

  # Deploy
  desc 'Deploy the Internal app to Firebase Distribution'
  lane :deploy_internal do
    firebase_app_distribution(
        app: "1:374168413412:ios:912d89b30767d8e5a038f1",
        ipa_path: "Moments.ipa",
        groups: "internal-testers",
        release_notes: "A new build for the Internal App", # Can customize it using Git history.
        firebase_cli_token: ENV["FIREBASE_API_TOKEN"]
    )
  end

  desc 'Deploy the Production app to TestFlight and App Store'
  lane :deploy_appstore do
    api_key = get_app_store_connect_api_key
    upload_to_app_store(
      api_key: api_key,
      app_identifier: "com.ibanimatable.moments",
      skip_metadata: true,
      skip_screenshots: true,
      precheck_include_in_app_purchases: false,
    )
  end

  desc 'Get App Store Connect API key'
  private_lane :get_app_store_connect_api_key do
    # The key needs to have App Manager role, see https://github.com/fastlane/fastlane/issues/17066
    key_content = ENV["APP_STORE_CONNECT_API_CONTENT"]  # Make sure setting this environment variable before call this lane.
    api_key = app_store_connect_api_key(
      key_id: "D9B979RR69",
      issuer_id: "69a6de7b-13fb-47e3-e053-5b8c7c11a4d1",
      key_content: "-----BEGIN EC PRIVATE KEY-----\n" + key_content + "\n-----END EC PRIVATE KEY-----",
      duration: 1200,
      in_house: false
    )

    api_key 
  end
end
